定义泛型集合的命名空间:System.Collections.Generic | 您所在的位置:网站首页 › sql command属于什么命名空间 › 定义泛型集合的命名空间:System.Collections.Generic |
本章导读 System.Collections.Generic和System.Collections集合的结构有很多相似之处,不同的是“Generic”提供的都是泛型集合,而“Collections”中的集合并不都支持泛型。 System.Collections.Generic是在C# 2.0中新加的命名空间,主要用来创建强类型集合,以提高类型安全和操作性能。 本章的讲解流程如图8-1所示。 图8-1 System.Collections.Generic的讲解流程 8.1 System.Collections.Generic简介本节主要介绍System.Collections.Generic包含的内容。泛型是C# 2.0中新增的一个命名空间,其设计目的主要是为了保障类型转换的安全,常应用在集合中。 8.1.1 什么是泛型泛型的意义在于,通过参数化类型来实现在同一份代码上对多种数据类型的操作。这种解释比较抽象,简单来讲,泛型就是利用参数化类型将类型抽象化,通常称为“类型多态”。 泛型使用“< >”将类型参数化,其中被尖括号包装的类型,必须是从System.Object继承的共有成员。泛型使用语法如下: List dinosaurs = new List(); 泛型的优点如下: (1)更强的类型安全。 (2)更好的复用,因为类型其实是一个参数。 (3)更高的效率。 (4)更清晰的约束。 8.1.2 System.Collections.Generic概述System.Collections.Generic用来管理泛型集合。此命名空间也包含System.Collections中的一些集合类,区别在于Generic提供了哪些集合的泛型版本。另外,System.Collections中某些集合是不具备泛型版本的。虽然Generic包含的是集合的泛型版本,但其基本操作方法与Collections中的集合类似。 Generic命名空间只有在C# 2.0中才有,而且泛型也是2.0中很关键的类型方式,学习本章的内容必须具备一定的集合知识。 8.1.3 System.Collections.Generic命名空间内的类组成集合是数据操作的关键,而泛型集合提高了操作的安全性。System.Collections.Generic命名空间内的类,负责管理并提供泛型集合的一些常用功能。表8-1列出了泛型集合常用的类及其说明。 表8-1 System.Collections.Generic命名空间内常用的类及其说明 类 名 类 说 明 Dictionary 键/值对集合 LinkedList 双向链表 List 是ArrayList的泛型等效类,属于动态数组 Queue 队列,先进先出的集合 SortedDictionary 可以排序的键/值对集合 SortedList 同SortedDictionary类似,可排序的键/值对集合 Stack 栈,后进先出的集合 System.Collections.Generic命名空间内的接口也非常重要,是自定义和扩展标准集合的关键。表8-2罗列的是System.Collections.Generic命名空间内的常用接口,本章所介绍的大部分类都继承这些接口。 表8-2 System.Collections.Generic命名空间内常用的接口及其说明 接 口 名 接口说明 ICollection Generic命名空间中类的基接口 IComparer 此接口定义比较对象的方法 IDictionary 表示键/值对的泛型集合 IEnumerable 定义枚举数 IEnumerator 支持在泛型集合上进行简单迭代 IEqualityComparer 此接口定义“相等”比较的方法 IList 可按照索引单独访问的一组对象 虽然System.Collections.Generic命名空间包含了多个泛型集合类,但这些类除去泛型使用语法不同外,其他操作方法和属性与System.Collections中的类相似。同时鉴于本书的篇幅限制,所以本章只介绍“Dictionary”,“LinkedList”和“SortedDictionary”类,而“Queue”,“SortedList”和“Stack”类的使用,读者可参考介绍“System.Collections”命名空间的有关章节。泛型集合中还有一个“List”类,其实就是一个泛型的ArrayList,学习List可以参考非泛型集合中对ArrayList的介绍。 8.2 泛型字典集合:Dictionary类Dictionary类又称为字典集合,本节介绍其内部构造及使用语法。在使用该类前,一定要弄清楚什么是字典,以及字典集合具备什么样的优点。 8.2.1 功能说明Dictionary类中保存的是键/值对集合,值可以为任意类型数据,其操作方法和构造都与Hashtable类相似,可以把Dictionary看成是Hashtable类的泛型版本。 Dictionary类也是通过“键”来检索数据的,这是提高检索速度的关键。Dictionary类默认初始容量为3。在实际应用中,如果可以测算出键/值对的数量,那么最好在定义Dictionary类时,指定其初始容量,这样在进行添加和移除操作时,就减少了大小调整这一环节。 8.2.2 语法定义Dictionary类的语法定义如下: [SerializableAttribute] [ComVisibleAttribute(false)] public class Dictionary : IDictionary, ICollection, IEnumerable, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback 此处需注意ICollection和ICollection的区别:一个是泛型集合接口,一个是非泛型集合接口。 Dictionary有7种构造方法,其中最常用的是默认不带任何参数的方法,使用语法如下: Dictionary openWith =new Dictionary(); 之所以说泛型是一种类型多态,是因为在定义泛型集合的时候,可以指定任意类型,如下所示的构造方法都正确: Dictionary dic1 =new Dictionary(); Dictionary dic1 = new Dictionary(); Dictionary dic1 = new Dictionary(); 8.2.3 属性详解Dictionary类的属性主要用来获取集合中的元素,表8-3详细列出了这些属性及其说明。 表8-3 Dictionary类的属性及其说明 属 性 名 属性说明 Comparer 判断字典中的键是否相等 Count 字典中的键/值对数量 Item 字典中指定键对应的值 Keys 字典中键的集合 Values 字典中值的集合 8.2.4 方法详解Dictionary类的方法用来操作字典中的键/值对,如添加、删除等。表8-4列出的是Dictionary类中常用的方法及其说明。 表8-4 Dictionary类常用的方法及其说明 方法名称 方法说明 Add 添加键/值对 Clear 清空键/值对 ContainsKey 判断字典中是否包含指定的主键 ContainsValue 判断字典中是否包含指定的值 Remove 移除指定的键/值对 TryGetValue 获取字典中的指定值 从上述方法中可以看出,泛型集合的方法与非泛型集合的方法基本相似。其实两者最主要的区别还是类型的参数化,而不是属性和方法的差异。 下面的代码演示如何使用Dictionary类中的方法,请仔细阅读注释。 Dictionary dic1 =new Dictionary(); dic1.Add(1, "北京");//添加键/值对 dic1.Add(2, "上海"); Response.Write("是否包含键‘2’"+dic1.ContainsKey(2)) ; Response.Write("是否包含值‘上海’"+dic1.ContainsValue("上海")) ; string myValue = ""; dic1.TryGetValue(1, out myValue);//获取指定键的值 8.2.5 典型应用:用Dictionary缓存数据库命令参数泛型类的主要优点是类型安全,这主要表现在当从集合中获取数据时,无须再进行显式类型转换,因为其已经用“”定义了类型参数。如获取HashTable中保存的命令参数,必须执行以下转换: SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey]; 而Dictionary泛型类,则可以不使用这种转换,而是直接用如下代码实现上述操作: SqlParameter[] cachedParms =parmCache[cacheKey]; 本例的目的是使用Dictionary实现命令参数的缓存,读者可对比“Hashtable”类的实例,了解泛型字典集合与非泛型字典集合在使用上的差异。本例的演示步骤如下。 打开VS2005,新建一个网站,命名为“DictionarySample”。 打开默认生成的Default.aspx页。在视图中添加两个“ListBox”控件。 按F7键切换到页面的代码视图。添加对数据库命名空间和集合命名空间的引用,代码如下: using System.Data.SqlClient; using System.Collections.Generic; 定义静态全局变量“parmCache”,用来缓存命令参数,定义语法如下: //定义缓存参数的泛型字典集合,注意static private static Dictionary parmCache = new Dictionary(); 在代码中添加两个方法“CacheParameters”和“GetCachedParameters”,其中CacheParameters用来添加键/值对到泛型字典中,GetCachedParameters用来获取泛型字典表中某键的值。两个方法的代码如下: //定义设置字典表参数的方法 public static void CacheParameters(string cacheKey, params SqlParameter[] commandParas) { parmCache[cacheKey] = commandParas; } //定义获取字典表参数的方法 public static SqlParameter[] GetCachedParameters(string cacheKey) { SqlParameter[] cachedParms = parmCache[cacheKey]; if (cachedParms == null)//判断是否为空 return null; return cachedParms; } 在页面的Page_Load事件中,为哈希表设置三个键/值对,并在ListBox1中显示字典表中所有的键。代码如下所示,注意黑体部分,其获取键值的方法与哈希表不同。 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { //设计3个参数集合 SqlParameter[] parmsA = new SqlParameter[] { new SqlParameter("@tabAid",SqlDbType.Int), new SqlParameter("@tabAname",SqlDbType.NVarChar,20) }; SqlParameter[] parmsB = new SqlParameter[] { new SqlParameter("@tabBid",SqlDbType.Int), new SqlParameter("@tabBname",SqlDbType.NVarChar,20), new SqlParameter("@tabBdate",SqlDbType.DateTime) }; SqlParameter[] parmsC = new SqlParameter[] { new SqlParameter("@tabCid",SqlDbType.Int), new SqlParameter("@tabCname",SqlDbType.NVarChar,20) }; //添加参数集合到哈希表中 CacheParameters("TableA", parmsA); CacheParameters("TableB", parmsB); CacheParameters("TableC", parmsC); //获取所有键 Dictionary.KeyCollection mykeys = parmCache.Keys; foreach (string strkey in mykeys) {//让ListBox1显示所有的键 ListBox1.Items.Add(strkey); } } } 本例的功能是当选择ListBox1中的键时,在ListBox2中显示此键对应的值,也就是所设置的参数集合。这需要在ListBox1的“SelectedIndexChanged”事件中完成此功能,代码如下: protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e) { //通过键,获取缓存的参数集合 SqlParameter[] parms = GetCachedParameters(ListBox1.SelectedValue); ListBox2.Items.Clear();//清空列表中的旧数据 foreach (SqlParameter parm in parms) {//遍历参数集合,显示所有的参数 ListBox2.Items.Add(parm.ParameterName); } } 注意:ListBox默认的“AutoPostBack”属性为false,为了实现数据的回传,必须将其设置为true。 按Ctrl+S组合键保存所有的代码,按F5键运行程序,可以发现ListBox1中罗列的是字典表中的键。当单击ListBox1中的某项时,ListBox2会显示对应的参数列表。 8.3 双向链表集合:LinkedList类LinkedList类管理的是双向链表,本节将介绍其概念、组成及应用。这些链表并不像C++中的那些链表一样,学起来特别抽象。C#中的链表类,对所有基本功能都进行了封装,使其应用更简单。 8.3.1 功能说明链表是C语言时期就存在的一种数据结构,是以链接方式存储的线性表,其中数据保存在线性表的节点中。节点内还有一个域,用来存放后继节点的指针,这种节点内只有一个指针域的被称为单向链表。如果节点内有两个指针域,一个指向前一个节点,一个指向后一个节点,那么这种链表被称为双向链表,本节介绍的LinkedList属于双向链表。 LinkedList类中的节点,属于“LinkedListNode”类型,由于LinkedList属于双向链表,所以其节点内包含两个指针域,用来获取前一个和后一个节点,在实际应用中,LinkedListNode节点类型包含属性“Next”和“Previous”代替了这两个指针域。 8.3.2 语法定义LinkedList类的语法定义如下: [SerializableAttribute] [ComVisibleAttribute(false)] public class LinkedList : ICollection, IEnumerable, ICollection, IEnumerable, ISerializable, IDeserializationCallback LinkedList继承了ISerializable和IDeserializationCallback,支持序列化和反序列化。 LinkedList有三种构造方法,最常用的是不带任何参数的构造方法,其构造语法如下: LinkedList mylink1 = new LinkedList(); 8.3.3 属性详解LinkedList类的属性主要是获取链表的节点,表8-5详细列出了这些属性及其说明。 表8-5 LinkedList类的属性及其说明 属 性 名 属性说明 Count 双向链表中的节点数 First 双向链表中的第一个节点 Last 双向链表中的最后一个节点 8.3.4 方法详解LinkedList类的方法用来操作双向链表中的节点,如添加、移除等。表8-6详细列出了这些方法及其说明。 表8-6 LinkedList类的方法及其说明 方法名称 方法说明 AddAfter 链表的当前节点后添加新节点 AddBefore 链表的当前节点前添加新节点 AddFirst 在链表的第一个节点前添加新节点 AddLast 在链表的最后一个节点后添加新节点 Clear 清空链表中的节点 Contains 判断链表是否包含某值 Find 查找指定值所在的节点。查找到一个后便结束查找 FindLast 查找指定值所在的节点。返回最后一个包含此值的节点 Remove 移除链表中指定的节点或值 RemoveFirst 移除链表中第一个节点 RemoveLast 移除链表中最后一个节点 下面的代码演示如何使用LinkedList类中的方法,由于方法比较多,请仔细阅读注释。 LinkedList mylink1 = new LinkedList();//初始化 mylink1.AddFirst("this ");//添加节点 mylink1.AddLast("is "); mylink1.AddLast(" Beijing"); LinkedListNode mynode = mylink1.Find("is ");//检索节点 Response.Write("上个节点的值:" + mynode.Previous.Value+"");//上一个节点 Response.Write("下个节点的值:" + mynode.Next.Value + "");//下一个节点 mylink1.RemoveLast();//移除节点 8.3.5 典型应用:用LinkedList实现记录的翻页虽然C# 2.0提供了很多功能强大的翻页控件库,但其速度仍然是个瓶颈。本例不使用任何翻页控件,而是使用LinkedList实现一个记录的翻页,这些记录都比较简单。在实际项目中,也可以考虑使用这种方法,实现复杂数据的翻页处理。 实例的演示步骤如下所述。 打开VS2005,新建一个网站,命名为“LinkedListSample”。 在“App_Code”目录下,添加一个类“UserInfo.cs”,用来自定义记录类型。代码设计如下: using System; public class UserInfo { private string _name; private string _city; public UserInfo(string name, string city) { _name = name; _city = city; } public string Name { set { _name = value; } get { return _name; } } public string City { set { _city = value; } get { return _city; } } } 按Ctrl+S组合键保存自定义的记录类型。 打开Default.aspx页。在视图中添加两个文本框,用来显示人名和城市;再添加两个按钮,用来实现上、下翻页,同时设计两个按钮的CommandName属性分别为“Next”和“Previous”。 将两个按钮的“Command”事件指向同一事件“Button1_Command”,代码如下: protected void Button1_Command(object sender, CommandEventArgs e) { UserInfo tmpUser=new UserInfo(txtName.Text.Trim(), txtCity.Text.Trim()); LinkedListNode mynode = myData.Find(tmpUser); if (e.CommandName == "Next") {//下一页
txtName.Text = mynode.Next.Value.Name; txtName.Text = mynode.Next.Value.City; } else { //上一页 txtName.Text = mynode.Previous.Value.Name; txtName.Text = mynode.Previous.Value.City; } } 引用泛型集合命名空间“System.Collections.Generic”。定义双向链表集合,代码如下: private static LinkedList myData = new LinkedList();//初始化 在“Page_Load”事件中,为链表赋值,同时显示当前的人名和城市,代码如下: protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { myData.AddLast(new UserInfo("张三","北京"));//设置数据 myData.AddLast(new UserInfo("王三", "上海")); myData.AddLast(new UserInfo("张明", "广州")); txtName.Text = "张三";//设置默认值 txtCity.Text = "北京"; } } 按Ctrl+S组合键保存所有的设计,再按F5键运行程序,单击上、下翻页按钮,测试记录的翻页情况。 8.4 排序泛型字典集合:SortedDictionary类SortedDictionary类是一个按键排序的字典集合,本节介绍SortedDictionary的主要功能及其使用方法。在使用时,一定要特别注意Sorted的作用。 8.4.1 功能说明SortedDictionary类是一个可以按键排序的Dictionary类,其功能类似于非泛型集合中的SortedList。在SortedDictionary类中,元素的键值是不允许改变的,系统自动通过键进行排序。 SortedDictionary类与SortedList类的区别如下。 — 内存的使用:SortedList类使用的内存比SortedDictionary类少。 — 填充速度:比较前提是要填充的列表已经排序,并一次性填充到字典中,此时SortedList的速度比SortedDictionary快。 — 添加和删除的速度:当单个在字典中添加和删除元素时,SortedDictionary具备更快的速度。 8.4.2 语法定义SortedDictionary类的语法定义如下: [SerializableAttribute] public class SortedDictionary : IDictionary, Icollection , IEnumerable, IDictionary, ICollection, IEnumerable 其中SortedDictionary继承ICollection和IDictionary的泛型接口。 SortedDictionary有4种构造方法,通常使用不带参数的方法来构造SortedDictionary的实例,使用语法如下: SortedDictionary myDic =new SortedDictionary(); 注意:类型参数可为继承System.Object的任意类型。 8.4.3 属性详解SortedDictionary类的属性主要是获取集合中的键/值对,表8-7详细列出了这些属性及其说明。 表8-7 SortedDictionary类的属性及其说明 属 性 名 属性说明 Count 排序字典中键/值对的数量 Item 指定键的值 Keys 排序字典中的键的集合 Values 排序字典中的值的集合 8.4.4 方法详解SortedDictionary类的方法用来对集合内的元素进行操作,如添加、删除等,表8-8列出的是SortedDictionary类中常用的方法及其说明。 表8-8 SortedDictionary类常用的方法列表 方法名称 方法说明 Add 在集合中添加键/值对 Clear 清空集合中的键/值对 ContainsKey 判断指定的键是否包含在集合中 ContainsValue 判断指定的值是否包含在集合中 Remove 从集合中移除指定的键/值对 TryGetValue 获取与指定键相关联的值 下面的代码演示如何使用SortedDictionary类中的方法: SortedDictionary mydic=new SortedDictionary();//初始化 mydic.Add(1,"海淀"); //添加元素 mydic.Add(2,"西城"); if (!mydic.ContainsValue("东城")) //判断是否包含指定的值 mydic.Add(3, "东城"); //添加元素 mydic.Remove(1); //移除键为1的元素 string myvalue = ""; mydic.TryGetValue(2,out myvalue); //获取键为2的元素的值 8.4.5 典型应用:使用SortedDictionary实现ListBox的排序本例利用SortedDictionary类的自动排序功能,实现ListBox控件的自动排序。要实现的功能是:当用户添加内容到ListBox中时,后台先将内容添加到SortedDictionary类的实例中,此时内容会自动排序,然后将ListBox的数据源绑定到SortedDictionary类的实例,这样就实现了ListBox控件的排序。 本实例的演示步骤如下所述。 打开VS2005,新建一个网站,命名为“SortedDictionarySample”。 打开Default.aspx页,在视图中添加一个ListBox,用来显示排序后的数据;两个TextBox,用来允许用户添加键/值对;一个按钮,用来实现用户的添加操作。 按F7键切换到代码视图,添加对泛型集合的命名空间“System.Collections.Generic”的引用。 定义页面的全局变量“mydic”,代码如下: static SortedDictionary mydic = new SortedDictionary(); 在第一次加载页面时,需要显示ListBox中已有的内容,代码如下: protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { mydic.Add("1", "首长");//添加集合中的元素 mydic.Add("3", "政委"); ListBox1.DataSource = mydic;//绑定数据源 ListBox1.DataBind(); } } 当用户输入键/值对,单击“添加”按钮时,需要实现内容的添加和排序,实现代码如下: protected void btnAdd_Click(object sender, EventArgs e) { try { mydic.Add(txtKey.Text, txtValue.Text); //添加元素,自动排序 ListBox1.DataSource = mydic; //绑定数据源 ListBox1.DataBind(); } catch (Exception ex) { Response.Write("要添加的键重复!"); } } 按Ctrl+S组合键保存代码,按F5键运行程序,并在“键”文本框内输入“2”,在“值”文本框内输入“将军”。单击“添加”按钮,可以发现ListBox进行了排序,并重新显示了排序后的数据。 8.5 小结本章介绍的是泛型集合命名空间System.Collections.Generic的内容,其中最主要的是“泛型”的意义。类型安全和约束是泛型集合的两大特点。 System.Collections.Generic和System.Collections中的很多接口和类都相似,掌握好System.Collections中的接口和类,是学习System.Collections.Generic的前提。 |
CopyRight 2018-2019 实验室设备网 版权所有 |